# -*- encoding: utf8 -*-
"""

.. module:: Parse
    :synopsis: Parsing utilities

.. moduleauthor:: Ruymán Reyes Castro <rreyes@ull.es>
.. moduleauthor:: Juan José Fumero Alfonso <jjfumero@gmail.com>

"""


import subprocess
from cStringIO import StringIO
# from yacf.Frontend.C import c_parser, c_ast

# from C import c_parser
# from Omp import omp_parser

import config


import re

class Prepro(object):
    pass

class CPrepro(Prepro):
    
    @staticmethod
    def removeComments(string):
        def replacer(match):
            s = match.group(0)
            if s.startswith('/'):
                return ""
            else:
                return s
        pattern = re.compile(
            r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
            re.DOTALL | re.MULTILINE
        )
        return re.sub(pattern, replacer, string)
    
    @staticmethod
    def remove_includes(source_code):
        """ Remove system includes from C sources
            Current removed includes match the following regexp::
            
                        #include <[A-Za-Z0-9.]+>
        """      
        identifier = "[A-Za-z0-9.-_]+"
        include_sys = '#include <' + identifier + '>'
        include_re = re.compile(include_sys)
        no_include = []
        for line in source_code:
            if not include_re.match(line):
                no_include += [line]
        return no_include
   
    @staticmethod
    def preprocess(code_source):
        """Apply preprocessor and Frontend.C
            :param code_source: string with the source code
            .. warning::
                This function requires *cpp* to be in PATH.
        """
        # prepro = "cpp -w -ansi -pedantic -CC -U __USE_GNU  -DLLC_TRANSLATION -P -I"
        prepro = "gcc -E -trigraphs -undef -pedantic  -w -ansi -CC -U __USE_GNU -xc - -DLLC_TRANSLATION -P -I"
        # default_include_file = config.WORKDIR +  'Frontend/include/llcomp_translation.h'
        # Prepare preprocessor pipe
        prepro_line = prepro + config.INCLUDE_DIR + " -I " + config.FAKE_LIBC # + ' -include ' + default_include_file
        p = subprocess.Popen(prepro_line, shell=True, bufsize=1, 
            stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
        # Send / Retrieve string to the preprocessor
        stripped_source = p.communicate(code_source)[0]
        return stripped_source

